package com.king.util

import java.text.SimpleDateFormat
import java.time.format.DateTimeFormatter
import java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset}
import java.util.{Calendar, Date}

object DateUtil {


  val datetimeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
  val dateFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")


  /**
    * 计算两日期月份差值（向下取整）
    *
    * @param first
    * @param second
    * @return
    */
  def monthsBetween(first: Date, second: Date): Int = {
    // 是否置为负值
    var isAssignMinus = false
    var bigger: Date = first
    var smaller: Date = second
    if (first.getTime < second.getTime) {
      bigger = second
      smaller = first
      isAssignMinus = true
    }
    val c1 = Calendar.getInstance()
    c1.setTime(bigger)
    val c2 = Calendar.getInstance()
    c2.setTime(smaller)

    val year1 = c1.get(Calendar.YEAR)
    val year2 = c2.get(Calendar.YEAR)
    val month1 = c1.get(Calendar.MONTH)
    val month2 = c2.get(Calendar.MONTH)
    val day1 = c1.get(Calendar.DAY_OF_MONTH)
    val day2 = c2.get(Calendar.DAY_OF_MONTH)
    // 获取年的差值
    var yearInterval = year1 - year2
    // 如果 c1 的“月-日”小于 c2 的“月-日”，则 yearInterval-- 为相差年份
    if (month1 < month2 || (month1 == month2 && day1 < day2)) {
      yearInterval -= 1
    }
    // 获取月份差值
    var monthInterval = (month1 + 12) - month2
    if (day1 < day2) {
      monthInterval -= 1
    }
    monthInterval %= 12
    if (isAssignMinus) -(yearInterval * 12 + monthInterval) else yearInterval * 12 + monthInterval
  }

  /**
    * 计算两个日期之间的天数差,日期格式为yyyy-MM-dd
    *
    * @param first  减数
    * @param second 被减数
    * @return 天数差
    * */
  def daysDiff(first: String, second: String): Int = {
    if (first == "" || second == "") {
      return -1
    }
    val sdf = new SimpleDateFormat("yyyy-MM-dd")
    val cal = Calendar.getInstance()
    cal.setTime(sdf.parse(first))
    val time1 = cal.getTimeInMillis
    cal.setTime(sdf.parse(second))
    val time2 = cal.getTimeInMillis
    val between_days = (time1 - time2) / (1000 * 3600 * 24)

    Integer.parseInt(String.valueOf(between_days))
  }

  /**
    * 获取指定日期往后n个月的日期,日期格式为yyyy-MM-dd
    *
    * @param date 基数日期
    * @param n    往后几个月,负数则为往前几个月
    * @return 对应日期,格式为yyyy-MM-dd
    *
    * */
  def currNMonth(date: String, n: Int): String = {
    //过去一月
    val sdf = new SimpleDateFormat("yyyy-MM-dd")
    val cal = Calendar.getInstance()
    cal.setTime(sdf.parse(date))
    cal.add(Calendar.MONTH, n)
    val m = cal.getTime
    sdf.format(m)
  }

  /**
    * 获取指定日期往后n天的日期,日期格式为yyyy-MM-dd
    *
    * @param date 基数日期
    * @param n    往后几天,负数则为往前几天
    * @return 对应日期,格式为yyyy-MM-dd
    *
    * */
  def currNDay(date: String, n: Int): String = {
    val sdf = new SimpleDateFormat("yyyy-MM-dd")
    val cal = Calendar.getInstance()
    //取时间
    cal.setTime(sdf.parse(date))
    cal.add(Calendar.DATE, n) //把日期往后增加一天.整数往后推,负数往前移动
    val d = cal.getTime //这个时间就是日期往后推一天的结果
    sdf.format(d)
  }


  /**
    * 获取当前日期,格式为yyyy-MM-dd
    *
    * @return 当前日期
    * */
  def currDate: String = new SimpleDateFormat("yyyy-MM-dd").format(new Date())

  /**
    * 获取当前日期,格式为yyyy-MM-dd
    *
    * @return 当前日期
    * */
  def currTime: String = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())

  /**
   * 获取当前小时,格式为yyyyMMddHH
   *
   * @return 当前日期
   * */
  def currHours: String = new SimpleDateFormat("yyyyMMddHH").format(new Date())

  /**
    * 获取昨天的日期,格式为yyyy-MM-dd
    *
    * @return
    */
  def yesterday: String = {
    val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd")
    val cal = Calendar.getInstance()
    cal.add(Calendar.DATE, -1)
    dateFormat.format(cal.getTime)
  }


  /**
    * 将时间戳转化成日期
    *
    * @param time
    * @return
    */
  def DateFormatReturnDate(time: String): Date = new SimpleDateFormat("yyyy-MM-dd").parse(time)

  /**
   * 获得UnixTimeStamp(秒)，返回格式为yyyy-MM-dd日期
   * 过期的方法，已被getDate(time)替代
   * @param time
   * @return
   */
  @Deprecated
  def getCsvDate(time: String): String = {
    getDate(time)
  }

  def getTimestamp_UTC(dateTime:String):Long = {
      LocalDateTime.parse(dateTime,datetimeFormatter).toInstant(ZoneOffset.UTC).toEpochMilli
  }

  def getDate_GMT0(time: String): String = {
    getDateByZoneId(time,"GMT+0")
  }
  def getDateTime_GMT0(time:String):String = {
    getDateTimeByZoneId(time,"GMT+0")
  }

  def getDate(time: String): String = {
    getDateByZoneId(time,"GMT+8")
  }
  def getDateTime(time:String):String = {
    getDateTimeByZoneId(time,"GMT+8")
  }

  def getDateByZoneId(time:String,zoneId:String):String = {
    val t = time.length match {
      case 10 => time.toLong * 1000
      case 13 => time.toLong
      case _ => time.substring(0,10).toLong * 1000
    }
    dateFormatter.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(t),ZoneId.of(zoneId)))
  }
  def getDateTimeByZoneId(time:String,zoneId:String):String = {
    val t = time.length match {
      case 10 => time.toLong * 1000
      case 13 => time.toLong
      case _ => time.substring(0,10).toLong * 1000
    }
    datetimeFormatter.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(t),ZoneId.of(zoneId)))
  }

  def getDateRange(args:Array[String]):(String,String)={
    args.length match {
      case 0 => (currNDay(yesterday,-1),currNDay(yesterday,1))
      case 1 => (currNDay(args.apply(0),-1),currNDay(args.apply(0),1))
      case 2 => (currNDay(args.apply(0),-1),currNDay(args.apply(1),1))
    }
  }

  def main(args: Array[String]): Unit = {
    println(getCsvDate("1438214400"))

   println(currHours)
  }
}
